<?php
/**
 * Scd Framework
 *
 * LICENSE
 *
 * This source file is subject to the BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.njwz.cn/license/
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to Eric <scd113@gmail.com> so we can send you a copy immediately.
 *
 * @category   Scd
 * @package    Scd
 * @copyright  Copyright (c) 2007 Blue Web Studio (http://www.njwz.cn)
 * @license    http://framework.njwz.cn/license/     
 * @version    $Id: Scd.php 2007-01-13 02:12:49Z eric $
 */

/**
 * Exception
 */
require_once 'Scd/Db/Exception.php';

class Scd_Db
{
	//数据库基本配置信息
	var $_config = null;

	var $_dbo = null;

	//是否连接
	var $_connector = null;

	var $_sql = null;

	var $_dbencode = null;

	/**
	 * @name 构
	 * @param array $config
	 * @return Scd_Db
	 */
	function Scd_Db( $config=null )
	{
		if ( $config !== null ) {
			//加载配置文件,默认一个default
			//$this->_config = is_object($config) ? $config : new Sonfig;
			
			$_conf = is_object($config) ? $config : new Sonfig();
			include_once($_conf->thrdPlugin.'/adodb/adodb.inc.php');
		}
		$this->setAdapter($_conf);
	}

	/**
	 * 数据库连接
	 *
	 * @return unknown
	 */
	function setAdapter($cf)
	{
		//连接数据库
		if ($this->_connector) {
			return $this->_connector;
		}else {
			//$this->_dbo = NewADOConnection("$driver://$login:$password@$host/$dbname?persist");
			if (!$this->_dbo = NewADOConnection("$cf->driver://$cf->login:$cf->password@$cf->host/$cf->dbname?persist")) {
				return new Scd_Db_Exception('Database connection error!');
			}
			define('ADODB_FETCH_ASSOC',2);
			$this->_dbo->SetFetchMode(ADODB_FETCH_ASSOC);
			//执行一次
			$this->setNames($cf->encoding);
		}
	}
	
	function setNames( $charset )
	{
		if (substr(mysql_get_server_info(), 0, 1) > 4 && !$_COOKIE['Scd']['regdb']) {
				$charset = in_array(strtolower($cf->ecoding), array('gbk', 'big5', 'utf8')) ? $cf->encoding : 'utf8';
				$this->query("SET NAMES '{$charset}'");
				$_COOKIE['Scd']['regdb'] = true;
		}
	}

	/**
	 * Get the internal database object
	 *
	 * @return object A JDatabase based object
	 */
	function &_getDBO()
	{
		return $this->_dbo;
	}

	/**
     * Prepares and executes an SQL statement with bound data.
     *
     * @param string $sql The SQL statement with placeholders.
     * @param array $bind An array of data to bind to the placeholders.
     * @return 
     */
	function query($sql, $debug = null)
	{
		$this->_sql = $sql;
		if ($debug) {
			print_result($this->_sql);
		}
		if ($this->_getDBO() == null) {
			return new Scd_Exception("Can`t Connection!");
		}
		if ($rs = $this->_dbo->Execute($sql)) {
			return $rs;
		}else {
			new Scd_Db_Exception('The SQL was Error.\n The SQL is : '.$sql);
			return false;
		}
		// connect to the database if needed
	}

	/**
     * Inserts a table row with specified data.
     *
     * @param string $table The table to insert data into.
     * @param array $bind Column-value pairs.
     * @return int The number of affected rows.
     */
	function insert($table, $bind)
	{
		// col names come from the array keys
		$cols = array_keys($bind);

		// build the statement
		$sql = "INSERT INTO `$table` "
		. '( `' . implode('`, `', $cols) . '`) '
		. 'VALUES ( "' . implode('", "', $bind) . '")';
		// execute the statement and return the number of affected rows
		//echo $sql;exit;
		$result = $this->query($sql, $bind);
		if ($result) {
			return true;
		}else {
			new Scd_Db_Exception("数据添加错误！");
		}
		//        return $result->rowCount();
	}

	/**
     * Updates table rows with specified data based on a WHERE clause.
     *
     * @param string $table The table to udpate.
     * @param array $bind Column-value pairs.
     * @param string $where UPDATE WHERE clause.
     * @return int The number of affected rows.
     */
	function update($table, $bind, $where)
	{
		$set = array();
		foreach ($bind as $col => $val) {
			$set[] = "`$col` = '$val'";
		}

		$where = $this->_prepareConditions($where);
		/*// build the statement
		if (is_array($where)) {
		$wheres = implode(', ', $where);
		}*/
		$sql = "UPDATE `$table` "
		. 'SET ' . implode(', ', $set)
		. (($where) ? " WHERE $where" : '');

		//        echo $sql;exit;
		// execute the statement and return the number of affected rows
		return $result = $this->query($sql);
	}

	/**
     * Deletes table rows based on a WHERE clause.
     *
     * @param string $table The table to udpate.
     * @param string $where DELETE WHERE clause.
     * @return int The number of affected rows.
     */
	function delete($table, $where)
	{
		$where = $this->_prepareConditions($where);
		// build the statement
		$sql = "DELETE FROM `$table` "
		. (($where) ? " WHERE $where" : '');

		// execute the statement and return the number of affected rows
		$result = $this->query($sql);
		if ($result) {
			return true;
		}
		return false;
	}

	/**
	 * Get the active query
	 *
	 * @access public
	 * @return string The current value of the internal SQL vairable
	 */
	function _toStringSql()
	{
		return "<pre>" . htmlspecialchars( $this->_sql ) . "</pre>";
	}

	/**
	 * Print out an error statement
	 *
	 * @param boolean If TRUE, displays the last SQL statement sent to the database
	 * @return string A standised error message
	 */
	function stderr( $showSQL = false ) {
		if ( $this->_errorNum != 0 ) {
			return "DB function failed with error number $this->_errorNum"
			."<br /><font color=\"red\">$this->_errorMsg</font>"
			.($showSQL ? "<br />SQL = <pre>$this->_sql</pre>" : '');
		} else {
			return "DB function reports no errors";
		}
	}

	/**
     * 分析查询条件，返回 WHERE 子句
     *
     * @param array $conditions
     *
     * @return string
     */
	function _prepareConditions($conditions)
	{
		if (is_null($conditions)) { return ''; }
		if (!is_array($conditions)) { return $conditions; }
		$where = array();
		foreach ($conditions as $key => $condition) {
			if (is_int($key)) {
				$condition = $this->_prepareConditions($condition);
				if ($condition != '') {
					$where[] = $condition;
				}
			} else {
				$where[] = "`".$key."` = '" . $condition."'";
			}
		}
		return implode(' AND ', $where);
	}
}

function _prepareConditions($conditions)
{
	return Scd_Db::_prepareConditions($conditions);
}
?>